package in.muton.edushare.imageProcessor.processingAPI;

import java.awt.RenderingHints;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.JPEGEncodeParam;

public class JAIWrapper implements IProcessingAPIWrapper {

	
	private static Log log = LogFactory.getLog(JAIWrapper.class);
	
	private PlanarImage image;
	private RenderedOp tempProcessingFile;
	public static final RenderingHints quality;
	public static final RenderingHints scaleUp;
	public static final float JPEGQuality = 0.92f;
	
	static{
		quality = new RenderingHints(
				RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		scaleUp = new RenderingHints(
					RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		
		Properties p = new Properties(System.getProperties());
		p.put("com.sun.media.jai.disableMediaLib", "true");
		System.setProperties(p);
	}
	
	private PlanarImage getTempProcessingFile(){
		return tempProcessingFile!=null?tempProcessingFile:image;
	}
	
	public void startNewProcessing() {
		this.tempProcessingFile = null;
	}
	
	public void loadFileFromPath(String absPath) {
		log.info("Loading file: "+ absPath);
		image = JAI.create("fileload", absPath);
	}

	public int getOrigWidth() {
		return image.getWidth();
	}

	public int getOrigHeight() {
		return image.getHeight();
	}

	public void scaleImage(int finalWidth, int finalHeight) {
		log.info("Original Image: [x: "+ getTempProcessingFile().getWidth()+",y: "+ getTempProcessingFile().getHeight()+"]");
		log.info("Resizing to: [x: "+finalWidth+", y: "+finalHeight+"]");
		
		double scaleX = 1.0*finalWidth/image.getWidth();
		double scaleY = 1.0*finalHeight/image.getHeight();
		double translationX = 0.0;
		double translationY = 0.0;
		
		if(scaleX < 1.0 && scaleY < 1.0){
			ParameterBlock pb = new ParameterBlock()
			.addSource(getTempProcessingFile())
			.add(scaleX)
			.add(scaleY)
			.add(translationX)
			.add(translationY);
			tempProcessingFile = JAI.create("SubsampleAverage", pb, quality);
		}else{
			ParameterBlock pb = new ParameterBlock()
			.addSource(getTempProcessingFile())
			.add((float)scaleX)
			.add((float)scaleY)
			.add((float)translationX)
			.add((float)translationY);
			tempProcessingFile = JAI.create("scale", pb, scaleUp);
		}
	}	

	public void cropImage(int cropX, int cropY, int cropRectWidth,int cropRectHeight) {
		log.info("Original Image: [x: "+ getTempProcessingFile().getWidth()+",y: "+ getTempProcessingFile().getHeight()+"]");
		log.info("Cropping: "+"\t\t[x: "+cropX+",y: "+cropY+",w: "+ cropRectWidth+",h: "+cropRectHeight+"]");
		if(cropRectWidth > getTempProcessingFile().getWidth())
			cropRectWidth = getTempProcessingFile().getWidth();
		if(cropRectHeight > getTempProcessingFile().getHeight())
			cropRectHeight = getTempProcessingFile().getHeight();
			
		log.info("Cropping Adjusted: "+"\t[x: "+cropX+",y: "+cropY+",w: "+ cropRectWidth+",h: "+cropRectHeight+"]");
		
		ParameterBlock pb = new ParameterBlock()
									.addSource(getTempProcessingFile())
									.add((float)cropX)
									.add((float)cropY)
									.add((float)cropRectWidth)
									.add((float)cropRectHeight);
		tempProcessingFile = JAI.create("crop", pb, quality);
	}

	public void saveImage(String absNewFilePath) {
		File file = null;
		FileOutputStream fout = null;
		try {
			file = new File(absNewFilePath);
			fout = new FileOutputStream(file);
			JPEGEncodeParam encodeParam = new JPEGEncodeParam();
			encodeParam.setQuality(JPEGQuality);
			ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", fout, encodeParam);
			/* TODO: ColorMap Conversion for GIF image's color loss  
			 * ColorConvertOp ccop = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY));
			 * ccop.filter(getTempProcessingFile().getAsBufferedImage(), null);*/
			encoder.encode(getTempProcessingFile().getAsBufferedImage());
		} catch (FileNotFoundException e) {
			log.fatal("Error during image processing", e);
		} catch (IOException e) {
			log.fatal("Error during image processing", e);
		} finally{
			
			try {
				if(fout!=null)
					fout.close();
			} catch (IOException e) {
				log.error("Could not close the FileOutputStream", e);
			}
		}
		
	}
	
}
